package stream;

import methodReferences.Student;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * Created with IntelliJ IDEA.
 * 类名：MainTest
 * 开发人员: CoderJu
 * 创建时间: 2019/3/7 21:23
 * 描述:
 * 版本：V1.0
 */
public class MainTest {
    public static void main(String[] args) {
        //createStream();
        //map();
        //flatMap();
       // mapToInt();
        //filter();
        //distinct();
        //sorted();
        //peek();
        //limit();
        //skip();
        //unordered();
        //forEach();
        //forEachOrdered();
        //toArray();
        //reduce();
        //collect();
        //min();
        //max();
        //count();
        //anyMatch();
        //allMatch();
        //noneMatch();
        //findFirst();
        //findAny();
        iterator();
    }

    /**
     * 创建流
     */
    public static void createStream(){
       // 通过集合提供的Stream()顺序流或者ParallelStream()并行流。
        List list = new ArrayList();
        list.add("555");
        list.add("333");
        list.add("888");
        Stream s = list.stream();
        Stream s2 = list.parallelStream();
        System.out.println("---------------");
        s.forEach(System.out::println);
        System.out.println("---------------");
        s2.forEach(System.out::println);
        System.out.println("---------------");

        //通过Arrays中的stream()获取数组流。
        String[] strings = {"1","2"};
        Stream arrayStreams =  Arrays.stream(strings);
        System.out.println("---------------");
        arrayStreams.forEach(System.out::println);
        System.out.println("---------------");

        //Stream中的静态of()方法。
        Stream streamOf = Stream.of(1,2,3,4,5,6);
        System.out.println("---------------");
        streamOf.forEach(System.out::println);
        System.out.println("---------------");

        //创建无线流
        Stream.generate(()->"stream"+new Random().nextInt()).limit(10).forEach(System.out::println);

        //创建空流
        Stream stream = Stream.empty();
        System.out.println("---------------");
        stream.forEach(System.out::println);
    }

    /**
     * map
     */
    public static void map(){
        List<Integer> numbers = Arrays.asList(1,2, 3,3, 2, 6, 6);
         numbers.stream().map(i->{
             if(i>3){
                 return i;
             }else {
                 return i*3;
             }
         }).forEach(System.out::println);
        System.out.println("--------------------");
         String[] strings = new String[]{"111","2222","333"};
         List re = Arrays.asList(strings).stream().map(x->x+"_JACK").collect(toList());
         Arrays.asList(strings).stream().map(x->x+"_JACK").forEach(System.out::println);

    }

    public static void flatMap(){
        List<Integer> numbers = Arrays.asList(1,2, 3,3, 2, 6, 6);
        numbers.stream().flatMap(y->Arrays.asList(y).stream()).distinct()
                .collect(toList())
                .forEach(System.out::println);
        System.out.println("--------------------");
        List<String> strings = Arrays.asList("1,2","8,99","342,24,32");
        strings.stream().flatMap(x->Arrays.stream(x.split(",")))
                .collect(toList()).
                forEach(System.out::println);
        System.out.println("--------------------");
        String[] words = new String[]{"Hello","World"};
        List<String> a = Arrays.stream(words)
                .map(word -> word.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(toList());
        a.forEach(System.out::print);
    }

    public static void mapToInt(){
        List<String> numbers = Arrays.asList("I","can","study","JAVA");
        long a = numbers.stream().mapToInt(x->x.length()).sum();
        System.out.println("mapToInt>>>"+a);
        a =  numbers.stream().mapToInt(m->{
            System.out.println("-------"+m);
            System.out.println(">>>>>"+m.indexOf("a"));
            return m.indexOf("a");
        }).sum();
        System.out.println("mapToInt>>>"+a);
        List<Integer> numbersint = Arrays.asList(1,2,3,3,2);
        double d = numbersint.stream().mapToInt(x->x*2).average().getAsDouble();
        System.out.println("mapToInt d>>>"+d);
        //通过boxed转化为流对象
        numbersint.stream().mapToInt(x->x*2).boxed().forEach(System.out::println);
    }

    public static void filter(){
        List<String> strings = Arrays.asList("I","can","study","JAVA");
        strings.stream().filter(x->x.indexOf("a")<0).forEach(System.out::println);
        System.out.println("----------------");
        (strings.stream().filter(y->y.length()>3).collect(toList())).stream().forEach(System.out::println);
        System.out.println("----------------");
    }

    public static void distinct(){
        List<String> strings = Arrays.asList("I","can","I","JAVA");
        strings.stream().distinct().forEach(System.out::println);
        List<Integer> numbers = Arrays.asList(1,2,3,2,4,5,5,5);
        System.out.println("----------------");
        numbers.stream().mapToInt(x->x*2).distinct().boxed().forEach(System.out::println);
    }

    public static void sorted(){
        //new Random().ints().limit(10).sorted().boxed().forEach(System.out::println);
        List<String> strings = Arrays.asList("I","can","study","jAVA");
        System.out.println("----------------");
        strings.stream().sorted().forEach(System.out::println);
        System.out.println("----------------");
        List<Integer> numbers = Arrays.asList(1,2,3,2,4,5,5,5);
        numbers.stream().distinct().sorted(Comparator.naturalOrder()).forEach(System.out::println);
        System.out.println("----------------");
        numbers.stream().distinct().sorted(Comparator.reverseOrder()).forEach(System.out::println);
        System.out.println("----------------");
        List<Person> list = new ArrayList<>();
        list.add(new Person(1,"张三",20));
        list.add(new Person(2,"李四",18));
        list.add(new Person(3,"王五",30));
        list.stream().sorted(Comparator.comparing(Person::getAge)).forEach(System.out::println);
        System.out.println("----------------");
        list.stream().sorted(Comparator.comparing(Person::getName)).collect(toList()).forEach(System.out::println);
    }

    public static void peek(){
        List<Person> list = new ArrayList<>();
        list.add(new Person(1,"张三",20,1000));
        list.add(new Person(2,"李四",18,500));
        list.add(new Person(3,"王五",30,3000));
        list.stream().peek(x->{
            if (x.getAge()>30){
                x.setSalary(x.getSalary()*3);
            }else {
                x.setSalary(x.getSalary()*1.5f);
            }
        }).forEach(System.out::println);
    }

    public static void limit(){
        List<String> strings = Arrays.asList("I","can","study","jAVA");
        strings.stream().limit(2).forEach(System.out::println);
        System.out.println("----------------");
        new Random().ints().limit(10).boxed().sorted().limit(3).forEach(System.out::println);
    }

    public static void skip(){
        Stream stream = new Random().ints().limit(10).sorted().boxed();
        List list = (List) stream.collect(toList());
        list.stream().forEach(x->System.out.println("随机10个数>>>>"+x));
        System.out.println("----------------");
        list.stream().skip(5).forEach(y->System.out.println("随机10个数 的后五个数>>>>"+y));
    }

    public static void unordered(){
        Stream stream = new Random().ints().limit(10).sorted().boxed();
        List list = (List) stream.collect(toList());
        list.stream().forEach(x->System.out.println("随机10个数>>>>"+x));
        System.out.println("----------------");
        Stream streamq  = (Stream) list.stream().unordered();
        streamq.forEach(System.out::println);
    }

    public static void forEach(){
        new Random( ).ints().limit(10).forEach(System.out::println);
    }

    public static void forEachOrdered(){
        List<String> strings = Arrays.asList("I","can","study","jAVA");
        strings.stream().parallel().forEach(x->System.out.println("forEach>>>>"+x));
        System.out.println("----------------");
        strings.stream().parallel().forEachOrdered(x->System.out.println("forEachOrdered>>>>"+x));
        System.out.println("----------------");
        strings.stream().forEach(x->System.out.println("forEach>>>>"+x));
        System.out.println("----------------");
        strings.stream().forEachOrdered(x->System.out.println("forEachOrdered>>>>"+x));
    }

    public static void toArray(){
        System.out.println(">>>>>"+new Random( ).ints().limit(10).toArray()) ;
        System.out.println("----------------");
        System.out.println(">>>>>"+(new Random( ).ints().limit(10).toArray()).getClass().toString()) ;
    }

    public static void reduce(){
        Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6);
        Integer integer = s.reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer+integer2;
            }
        }).get();
        System.out.println("integer:"+integer);
        System.out.println("----------------");
        //等价于
       /* Integer integer1 = s.reduce((x,y)->x+y).get();
        System.out.println("integer1:"+integer1);*/
        Stream<Integer> s1 = Stream.of(1, 2, 3, 4, 5, 6);
        Integer max = s1.reduce((x,y)->x>y?x:y).get();
        System.out.println("max:"+max);
        System.out.println("----------------");
        Stream<String> s2 = Stream.of("1", "2", "3", "4", "5", "6");
        String str = s2.reduce("JACK",(x,y)->x.concat(y));
        System.out.println("str:"+str);

        Stream<String> s3 = Stream.of("1", "2", "2", "4", "5","5");
        Predicate predicate = t->t.equals("2");
        s3.reduce(new ArrayList(),(x,y)->{
            if (!predicate.test(y)){
                x.add(y);
            }
            return x;
        },(x1,x2)->x1).forEach(System.out::println);
    }


    public static void collect(){
        List list1 = new ArrayList();
        Stream<String> s4 = Stream.of("1", "2", "2", "4", "5","5");
        s4.collect(()->new ArrayList(),(list,y)->{
            if (!y.equals("2")){
                System.out.println("1>>>>:"+y);
                list.add(y);
                System.out.println("2>>>>:"+list);
            }
            System.out.println("3>>>>:"+list);
        },(x1,y1)->{
        }).forEach(System.out::println);
        System.out.println("--------------------");
        Stream<String> s5 = Stream.of("1", "2", "2", "4", "5","5");
        s5.collect(()->new ArrayList(),(list,y)->{
            if (!y.equals("2")){
                System.out.println("1>>>>:"+y);
                list.add(y);
                System.out.println("2>>>>:"+list);
            }
            System.out.println("3>>>>:"+list);
        },(x1,y1)->{
            System.out.println("4>>>>>:"+x1);
            x1.addAll(y1);
            System.out.println("5>>>>>:"+x1);
        }).forEach(System.out::println);
        list1.forEach(System.out::println);
        System.out.println("--------------------");
        Stream<Integer> stream = Stream.of(1, 2, 3, 4).filter(p -> p > 2);
         stream.collect(() -> new ArrayList<>(), (list, item) -> list.add(item), (one, two) -> {
            one.addAll(two);
            System.out.println("one : "+one);
        }).forEach(System.out::println);
        System.out.println("--------------------");
        Stream<String> s6 = Stream.of("1", "2", "2", "4", "5","5");
        Map map =  s6.collect(Collectors.toMap(
                x->x+"Key",
                y->y+"Value",
                (x1,y1)->x1 +","+y1
                ));
        System.out.println(">>>>"+map);
    }

    public static void min(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        Optional<Integer> min =  s4.min(Comparator.comparing(Function.identity()));
        System.out.println("min>>>>"+min);
        System.out.println("--------------------");
        Stream<Integer> s5 = Stream.of(1, 2, 2, 4, 5,5);
        Optional<Integer> min1 =  s5.min((x,y)->x.compareTo(y));
        System.out.println("min1>>>>"+min1);
        System.out.println("--------------------");
        Stream<Integer> s6 = Stream.of(1, 2, 2, 4, 5,5);
        Optional<Integer> min2 =  s6.min((x,y)->x>y?x:y);
        System.out.println("min2>>>>"+min2);
    }

    public static void max(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        Optional<Integer> max =  s4.max(Comparator.comparing(Function.identity()));
        System.out.println("max>>>>"+max);
        System.out.println("--------------------");
        Stream<Integer> s5 = Stream.of(1, 2, 2, 4, 5,5);
        Optional<Integer> max1 =  s5.max((x,y)->x.compareTo(y));
        System.out.println("max1>>>>"+max1);
    }

    public  static void count(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        System.out.println("count>>>>>"+s4.count());
    }

    public  static void anyMatch(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        boolean result  =  s4.anyMatch(x->x==2);
        System.out.println("result>>>>>"+result);
    }

    public  static void allMatch(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        boolean result  =  s4.allMatch(x->x==1);
        System.out.println("result>>>>>"+result);
        System.out.println("--------------------");
        Stream<Integer> s3 = Stream.of(1, 2, 2, 4, 5,5);
        boolean result1  =  s3.allMatch(x->x==1||x==2||x==4||x==5);
        System.out.println("result1>>>>>"+result1);
    }

    public  static void noneMatch(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        boolean result  =  s4.noneMatch(x->x==1);
        System.out.println("result>>>>>"+result);
        System.out.println("--------------------");
        Stream<Integer> s3 = Stream.of(1, 2, 2, 4, 5,5);
        boolean result1  =  s3.noneMatch(x->x==8);
        System.out.println("result1>>>>>"+result1);
    }

    public  static void findFirst(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        Optional result  =  s4.findFirst();
        System.out.println("result>>>>>"+result);
        System.out.println("--------------------");
        Stream<Integer> s3 = Stream.of(8, 2, 2, 4, 5,5);
        Optional result1  =  s3.findFirst();
        System.out.println("result1>>>>>"+result1);
    }

    public  static void findAny(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        Optional result  =  s4.findAny();
        System.out.println("result>>>>>"+result);
        System.out.println("--------------------");
        Stream<Integer> s3 = Stream.of(81, 2, 2, 4, 5,5);
        Optional result1  =  s3.findAny();
        System.out.println("result1>>>>>"+result1);
    }

    public  static void iterator(){
        Stream<Integer> s4 = Stream.of(1, 2, 2, 4, 5,5);
        Iterator result  =  s4.iterator();
        while (result.hasNext()){
            System.out.println(result.next());
        }
    }

}
